home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1995 November / Macworld Nov ’95.toast / Developers / Sources / cellusoftspritesrc.sit.hqx / cellusoftspritesrc.sit / Cellusoft Graphics / Animation Project.c next >
Encoding:
Text File  |  1994-01-05  |  10.8 KB  |  356 lines

  1. //• The following program demonstrates most of the routines created in the 
  2. //• unit CellusoftAnimations.
  3.  
  4. //• What does the program do?
  5. //• The application created by this program will display a window of 
  6. //• size 300 X 300, with a picture taken from PICT resource ID 130 and 
  7. //• animate a bunch of rotating eyeballs, each of which will rotate from 
  8. //• one side of the window to the other continuously.  
  9. //• The graphics for the eyeballs are from PICT ID 128 and the masks are 
  10. //• from PICT ID 129.  
  11. //• In order to gain fuller understanding of the program, you may wish to 
  12. //• look through the resource file used by the program.
  13.  
  14. //• Animation Project© 1993 Tony Small All Rights Reserved WorldWide
  15.  
  16. //• Many parts of the program do not directly pertain to routines in 
  17. //• CelluSoftAnimations, but all is thoroughly  documented to give further 
  18. //• insight into graphics, mac design and animation programming.
  19.  
  20. //• This demo was translated to C by Matt Burch - Singularity Software.
  21.  
  22.  
  23. #include<stdio.h>
  24. #include<Windows.h>
  25.  
  26. #define abs(a)     ((a)<0?- (a): (a))
  27.  
  28. #define    STACKSPACE    32768L    //• used by ToolBoxInit ()
  29. #define MaxEyes    6            //• the max number of eyes on the screen. 
  30.                             //• This shouldn't be bigger than MaxAnimations
  31.  
  32. extern Rect tr[5];            //• an array of temporary rects that we use 
  33.                             //• periodically
  34.  
  35. //• These rects are required by the animation routines.
  36. struct eyeballs
  37. {                            
  38.     Rect currentRect,     //• Where the eyeball is currently on the screen.
  39.  
  40.     lastRect,             //• Where the eyeball was on the screen in the 
  41.                         //• last animation loop.
  42.     pictRect;            //• Where the picture of the current eyeball 
  43.                         //• is located in the Eyeball port.
  44.     short step;            //• Specifies at what stage the eyeball is in its 
  45.                         //• movement.
  46.     Boolean goingLeft;    //• If this is true, then the eyeball is moving 
  47.                         //• left.  If not, then right.
  48. };
  49.  
  50. //• The variable for the main window.
  51. WindowPtr mainWindow, testWin;                        
  52.  
  53. //• The variables for the ports.
  54. GrafPtr    PureBack, Eyeball, Eyeballmask, offLoad;    
  55. GDHandle PureBackDevice, EyeballDevice, EyeballmaskDevice, offLoadDevice;
  56.  
  57. //• The array of eyeball records.
  58. struct eyeballs    eyeBallArray[MaxEyes+1];            
  59.  
  60.  
  61. //• This function gives a random number from 1 to range.
  62. short Randomize (short range)    
  63. {
  64.     short rawResult;
  65.     rawResult = Random ();
  66.     rawResult = abs (rawResult);
  67.     return (rawResult % range);
  68. }
  69.     
  70.     
  71. //• This procedure initializes all variables of all eyeball records in the 
  72. //• eyeballArray.
  73. //• It sets the currentRect for each eyeball at a random rect within the 
  74. //• bounds of the window.
  75. //• It sets the step to 1 so each eyeball will start out flat on the screen.
  76. //• It randomly sets the goingleft boolean variable.
  77. //• It sets the pictRect to the area in the eyeball port that holds the 
  78. //• flat eyeball picture.
  79.  
  80. void InitializeEyes ()
  81. {
  82.     short i;
  83.  
  84.     for (i=1;i<=MaxEyes;i++)
  85.     {
  86.         eyeBallArray[i].currentRect.left = Randomize (300 - 19);
  87.         eyeBallArray[i].currentRect.top = Randomize (300 - 10);
  88.         eyeBallArray[i].currentRect.right = eyeBallArray[i].currentRect.left + 19;
  89.         eyeBallArray[i].currentRect.bottom = eyeBallArray[i].currentRect.top + 10;
  90.         eyeBallArray[i].lastRect = eyeBallArray[i].currentRect;
  91.         eyeBallArray[i].step = 1;
  92.         if (Randomize (2) == 1)
  93.             eyeBallArray[i].goingLeft = TRUE;
  94.         else
  95.             eyeBallArray[i].goingLeft = FALSE;
  96.         SetRect (&eyeBallArray[i].pictRect, 0, 0, 19, 10);
  97.     }
  98. }
  99.     
  100.         
  101. //• These lengthly procedures do not pertain to specific animation routines.
  102. //• They merely see at what step the specified eyeball is at, then change 
  103. //• the step, currentrect, and pictRect accordingly.
  104. //• One also very important thing thiese procedure does is set lastRect to 
  105. //• the currentRect BEFORE the new currentRect is set.
  106.  
  107. void ChangeEye (
  108.     short num, 
  109.     short newIn, 
  110.     short left, 
  111.     short top, 
  112.     short right, 
  113.     short bottom, 
  114.     short mleft, 
  115.     short mtop, 
  116.     short mright, 
  117.     short mbottom)
  118. {
  119.     SetRect (&eyeBallArray[num].pictRect, left, top, right, bottom);
  120.     MoveRect (&eyeBallArray[num].currentRect, mleft, mtop, mright, mbottom);
  121.     eyeBallArray[num].step = newIn;
  122. }
  123.  
  124. void CalcEyeBall (short num)
  125. {
  126.     //• Very important!!!!
  127.     eyeBallArray[num].lastRect = eyeBallArray[num].currentRect;             
  128.     switch (eyeBallArray[num].step)
  129.     {
  130.         case 1: 
  131.             //• Determine which direction the eyeball is going.
  132.             if (eyeBallArray[num].goingLeft)            
  133.                 ChangeEye (num, 20, 0, 11, 19, 23, 0, -2, 0, 0);
  134.             else
  135.                 ChangeEye (num, 40, 0, 167, 19, 179, 0, -2, 0, 0);
  136.         break;
  137.         case 20: 
  138.             ChangeEye (num, 21, 0, 24, 18, 38, 1, -2, 0, 0);
  139.         break;
  140.             
  141. //• The above for example does the following:
  142. //• If the step equals 20, then change the step to 21, change the 
  143. //• PictRect to coordinates 0,24,18,38, and move the currentRect, one 
  144. //• pixel over from the left and two pixels up from the top.
  145.  
  146.         case 21: 
  147.             ChangeEye (num, 22, 0, 39, 16, 56, 2, -3, 0, 0);
  148.         break;
  149.         case 22: 
  150.             ChangeEye (num, 23, 0, 57, 14, 75, 2, -1, 0, 0);
  151.         break;
  152.         case 23: 
  153.             ChangeEye (num, 24, 0, 76, 12, 95, 2, -1, 0, 0);
  154.         break;
  155.         case 24: 
  156.             ChangeEye (num, 25, 0, 96, 11, 115, 1, 0, 0, 0);
  157.         break;
  158.         case 25: 
  159.             ChangeEye (num, 26, 0, 116, 14, 134, 0, 1, 3, 0);
  160.         break;
  161.         case 26: 
  162.             ChangeEye (num, 27, 0, 135, 17, 151, 0, 2, 3, 0);
  163.         break;
  164.         case 27: 
  165.             ChangeEye (num, 28, 0, 152, 18, 166, 0, 2, 1, 0);
  166.             break;
  167.         case 28: 
  168.             ChangeEye (num, 29, 0, 167, 19, 179, 0, 2, 1, 0);
  169.         break;
  170.         case 29: 
  171.             //• If the eyeball is at the edge of the screen, 
  172.             //• then change direction.
  173.             if (eyeBallArray[num].currentRect.right > 300)    
  174.             {
  175.                 ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0);
  176.                 eyeBallArray[num].goingLeft = FALSE;
  177.             }
  178.             else
  179.                 ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0);
  180.  
  181.         break;
  182.         case 40: 
  183.             ChangeEye (num, 41, 0, 152, 18, 166, 0, -2, -1, 0);
  184.         break;
  185.         case 41: 
  186.             ChangeEye (num, 42, 0, 135, 17, 151, 0, -2, -1, 0);
  187.         break;
  188.         case 42: 
  189.             ChangeEye (num, 43, 0, 116, 14, 134, 0, -2, -3, 0);
  190.         break;
  191.         case 43: 
  192.             ChangeEye (num, 44, 0, 96, 11, 115, 0, -1, -3, 0);
  193.         break;
  194.         case 44: 
  195.             ChangeEye (num, 45, 0, 76, 12, 95, -1, 0, 0, 0);
  196.         break;
  197.         case 45: 
  198.             ChangeEye (num, 46, 0, 57, 14, 75, -2, 1, 0, 0);
  199.         break;
  200.         case 46: 
  201.             ChangeEye (num, 47, 0, 39, 16, 56, -2, 1, 0, 0);
  202.         break;
  203.         case 47: 
  204.             ChangeEye (num, 48, 0, 24, 18, 38, -2, 3, 0, 0);
  205.         break;
  206.         case 48: 
  207.             ChangeEye (num, 49, 0, 11, 19, 23, -1, 2, 0, 0);
  208.         break;
  209.         case 49: 
  210.             //• If the eyeball is at the edge of the screen, 
  211.             //• then change direction.
  212.             if (eyeBallArray[num].currentRect.left < 0)  
  213.             {
  214.                 ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0);
  215.                 eyeBallArray[num].goingLeft = true;
  216.             }
  217.             else
  218.                 ChangeEye (num, 1, 0, 0, 19, 10, 0, 2, 0, 0);
  219.         }
  220.     }
  221.  
  222. //• For each record in the eyeballarray, this procedure calls the above 
  223. //• procedure, then installs the eyeball into the Animation array with 
  224. //• setAnimation.
  225. void DoTheEyes ()        
  226. {
  227.     short i;
  228.  
  229.     for (i = 1; i <= MaxEyes; i++)
  230.     {
  231.         CalcEyeBall (i);
  232.         SetAnimation (eyeBallArray[i].lastRect, eyeBallArray[i].currentRect, eyeBallArray[i].pictRect, Eyeball, Eyeballmask);  //• eyeball and eyeball mask are the two
  233.     }
  234. }
  235.     
  236.     
  237. //• This function centers a rect on the screen with dimensions of width 
  238. //• and height.
  239. //• This function is called when the Mainwindow is created.
  240. void CenterWindow (Rect *r, short width, short height)
  241. {
  242.     short screenHeight, screenWidth, i;
  243.  
  244.     //• Get the exact pixel height and width of the screen.
  245.     screenWidth = screenBits.bounds.right - screenBits.bounds.left;        
  246.     screenHeight = screenBits.bounds.bottom - screenBits.bounds.top;
  247.  
  248.     tr[1].top = (screenHeight - height) / 2 + 20;
  249.     tr[1].left = (screenWidth - width) / 2;
  250.     SetRect (*&r, tr[1].left, 
  251.                  tr[1].top, 
  252.                  tr[1].left + width, 
  253.                  tr[1].top + height);
  254. }
  255.     
  256.     
  257. //• This function creates a centered window that’s 300x300 pixels in size.
  258. void SetUpWindow ()        
  259. {
  260.     Rect r;
  261.     CenterWindow (&r, 300, 300);                //• center it first
  262.     mainWindow = NewCWindow (nil, &r,         //• then initialize it
  263.         "\p", TRUE, plainDBox, nil, FALSE,
  264.         -1L);    
  265.     SetPort (mainWindow);            //• Set the port to this new window.
  266.     ShowWindow (mainWindow);            //• Reveal the window.
  267. }
  268.  
  269.  
  270. //• This function creates offscreen ports for our animation.
  271. //• See the CellusoftAnimations file for more information.
  272. void InitializePorts ()            
  273. {                            
  274.     //• Create a color port with PICT ID 130 of dimensions 300 X 300.
  275.     CreateOffScreen (300, 300, 0, &PureBack, 130);          
  276.     //• Create a blank color port of dimensions 300 X 300.
  277.     CreateOffScreen (300, 300, 0, &offLoad, -1);          
  278.     //• Create a color port with PICT ID 128 of dimensions 19 X 179.
  279.     CreateOffScreen (19, 179, 0, &Eyeball, 128);        
  280.     //• Create a black and white port with PICT ID 129 of dimensions 19 X 179.
  281.     CreateOffScreen (19, 179, 1, &Eyeballmask, 129);    
  282. }
  283.  
  284.  
  285. //• This procedure copies the picture from port PureBack to the MainWindow.
  286. void DrawBackGround ()    
  287. {
  288.     Copy (PureBack, mainWindow, PureBack->portRect, mainWindow->portRect);
  289. }
  290.  
  291.  
  292. void WriteMessage (GrafPtr theGraf)
  293. {
  294.     short fontnumber;
  295.     Str255 thestring;
  296.     
  297.     SetPort (theGraf);
  298.     GetFNum ("\pChicago", &fontnumber);
  299.     TextFont (fontnumber);
  300.     TextSize (12);
  301.     MoveTo (5, 270);
  302.     DrawString ("\pClick The Mouse To Quit The Demonstration.");
  303. }
  304.  
  305.  
  306. //• This procedure draws the message 'Click the Mouse to Quit the 
  307. //• Demonstration' at coordinates 5, 270.
  308. void DrawMessage ()                 
  309. {                            
  310.     //• This message is written on both the pureback port and the 
  311.     //• MainWindow so that the eyeballs will not erase the message.
  312.     WriteMessage (PureBack);        
  313.     //• if the eyballs and the message happens to collide.
  314.     WriteMessage (mainWindow);
  315. }
  316.  
  317.  
  318. void main ()
  319. {
  320.     ToolBoxInit ();                //• Initialize the Mac
  321.     GetDateTime (&randSeed);        //• Initialize the random number generator in the Macintosh system.
  322.     HideCursor ();                //• Hide the cursor.
  323.     SetUpWindow ();                //• Create the window.
  324.     InitializePorts ();            //• Create the ports.
  325.     DrawBackGround ();            //• Draw the picture onto the window
  326.     InitializeEyes ();            //• Initialize the variables for the eyeballs.
  327.     SetPort (mainWindow);        //• Set the current port to the main window.
  328.     DrawMessage ();                //• Draw the message onto the screen.
  329.     while (!Button ())            //• While the mouse button is not down, perform the following loop.
  330.     {
  331.         SetPort (mainWindow);                            //• make sure we’re drawing to the main window
  332.         InitAnimations ();                                //• Reset the animations.
  333.         DoTheEyes ();                                    //• Move the eyes and load them into the animation array.
  334.         AnimateArray (PureBack, offLoad, mainWindow);    //• Animate the animation array.
  335.     }                                                    //• The preserved background graphic is in the port pureback.
  336.                                                         //• The port to be used for workspace is offLoad.
  337.                                                         //• The port to draw the animations to is the window MainWindow.
  338.         
  339.     ShowCursor ();                //• Show the cursor before exiting.
  340. }
  341.  
  342. ToolBoxInit ()                    //• this initializes the Mac’s Toolbox
  343. {
  344.     SetApplLimit (GetApplLimit () - (STACKSPACE - DefltStack));
  345.  
  346.     InitGraf (&thePort);
  347.     InitCursor ();
  348.     InitFonts ();
  349.     InitWindows ();
  350.     InitMenus ();
  351.     TEInit ();
  352.     InitDialogs (0L);
  353.     InitCursor ();
  354.     MaxApplZone ();
  355. }
  356.